home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / Found / FWString / Sources / FWStrs.cpp < prev    next >
Encoding:
Text File  |  1995-11-08  |  30.5 KB  |  913 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWStrs.cpp
  4. //    Release Version:    $ 1.0d11 $
  5. //
  6. //    Copyright:    (c) 1993, 1995 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWFound.hpp"
  11.  
  12. #ifdef FW_BUILD_MAC
  13. #include <Types.h>
  14. #endif
  15.  
  16. #ifndef FWEXCLIB_H
  17. #include "FWExcLib.h"
  18. #endif
  19.  
  20. #ifndef FWSTRS_H
  21. #include "FWStrs.h"
  22. #endif
  23.  
  24. #ifndef FWPRIDEB_H
  25. #include "FWPriDeb.h"
  26. #endif
  27.  
  28. #ifndef FWSTRTOO_H
  29. #include "FWStrToo.h"
  30. #endif
  31.  
  32. #if FW_LIB_EXPORT_PRAGMAS
  33. #pragma lib_export on
  34. #endif
  35.  
  36. #ifdef FW_BUILD_MAC
  37. #pragma segment Strings
  38. #endif
  39.  
  40. //========================================================================================
  41. //    CLASS FW_CByteString
  42. //========================================================================================
  43.  
  44. //----------------------------------------------------------------------------------------
  45. //    FW_CByteString destructor
  46. //----------------------------------------------------------------------------------------
  47.  
  48. FW_CByteString::~FW_CByteString()
  49. {
  50. }
  51.  
  52. //----------------------------------------------------------------------------------------
  53. //    FW_CByteString default constructor
  54. //----------------------------------------------------------------------------------------
  55.  
  56. FW_CByteString::FW_CByteString() :
  57.     fRepresentation(0),
  58.     fByteLength(0),
  59.     fCapacity(0)
  60. {
  61. }
  62.  
  63. //----------------------------------------------------------------------------------------
  64. //    FW_CByteString copy constructor
  65. //----------------------------------------------------------------------------------------
  66.  
  67. FW_CByteString::FW_CByteString(const FW_CByteString &string) :
  68.     fRepresentation(0),
  69.     fByteLength(0),
  70.     fCapacity(0)
  71. {
  72.     FW_UNUSED(string);
  73. }
  74.  
  75. //----------------------------------------------------------------------------------------
  76. //    FW_CByteString::AppendBytes
  77. //----------------------------------------------------------------------------------------
  78.  
  79. void FW_CByteString::AppendBytes(const FW_Char* source, FW_ByteCount numberBytes)
  80. {
  81.     InsertBytes(source, numberBytes, fByteLength);
  82. }
  83.  
  84. //----------------------------------------------------------------------------------------
  85. //    FW_CByteString::DeleteBytes
  86. //----------------------------------------------------------------------------------------
  87.  
  88. void FW_CByteString::DeleteBytes(FW_ByteCount numberBytes, FW_ByteCount position)
  89. {
  90.     FW_ASSERT(numberBytes >= 0);
  91.     FW_ASSERT(position>=0 && position<=fByteLength);
  92.     FW_ASSERT(position+numberBytes <= fByteLength);
  93.     if (numberBytes > 0)
  94.     {
  95.         FW_Byte* atPosition = BytePositionInString(position);
  96.         FW_ByteCount toMove = fByteLength-(position+numberBytes);
  97.         FW_BlockMove(atPosition+numberBytes, atPosition, toMove);
  98.         PrivSetByteLength(fByteLength - numberBytes);
  99.     }
  100. }
  101.  
  102. //----------------------------------------------------------------------------------------
  103. //    FW_CByteString::InsertBytes
  104. //----------------------------------------------------------------------------------------
  105.  
  106. void FW_CByteString::InsertBytes(const FW_Char* bytes, 
  107.                                  FW_ByteCount numberBytes,  
  108.                                  FW_ByteCount position)
  109. {
  110.     FW_ASSERT(bytes != NULL);
  111.     FW_ASSERT(numberBytes >= 0);
  112.     FW_ASSERT(position>=0 && position<=fByteLength);
  113.     if (numberBytes > 0)
  114.     {
  115.         FW_ByteCount capacityNeeded = fByteLength+numberBytes;
  116.         GrowCapacity(capacityNeeded);
  117.         FW_ASSERT(fCapacity >= capacityNeeded);
  118.         
  119.         FW_Byte* blockToMove = BytePositionInString(position);
  120.         FW_BlockMove(blockToMove, 
  121.                      blockToMove+numberBytes, 
  122.                      fByteLength-position+sizeof(FW_Char));
  123.         FW_BlockMove((const FW_Byte*)bytes, blockToMove, numberBytes);
  124.         PrivSetByteLength(capacityNeeded);
  125.     }
  126. }
  127.  
  128. //----------------------------------------------------------------------------------------
  129. //    FW_CByteString::ReplaceBytes
  130. //----------------------------------------------------------------------------------------
  131.  
  132. void FW_CByteString::ReplaceBytes(const FW_Char* source, 
  133.                                   FW_ByteCount numberBytes, 
  134.                                   FW_ByteCount position)
  135. {
  136.     FW_ASSERT(source != NULL);
  137.     FW_ASSERT(numberBytes >= 0);
  138.     FW_ASSERT(position>=0 && position<=fByteLength);
  139.     if (numberBytes > 0)
  140.     {
  141.         FW_ByteCount bytesToReplace = FW_Minimum(numberBytes, fByteLength-position);
  142.  
  143.         FW_ByteCount capacityNeeded = fByteLength - bytesToReplace + numberBytes;
  144.         FW_ByteCount capacity = GrowCapacity(capacityNeeded);
  145.         FW_ASSERT(capacityNeeded <= capacity);
  146.         
  147.         FW_ByteCount bytesAtEndToMove = fByteLength - position - bytesToReplace;
  148.         if (bytesAtEndToMove>0 && bytesToReplace!=numberBytes)
  149.         {
  150.             FW_BlockMove(BytePositionInString(position+bytesToReplace),
  151.                          BytePositionInString(position+numberBytes),
  152.                          bytesAtEndToMove);
  153.         }
  154.         
  155.         FW_BlockMove((const FW_Byte*)source, BytePositionInString(position), numberBytes);
  156.         PrivSetByteLength(capacityNeeded);
  157.     }
  158. }
  159.  
  160. //----------------------------------------------------------------------------------------
  161. //    FW_CByteString::ReplaceAllBytes
  162. //----------------------------------------------------------------------------------------
  163.  
  164. void FW_CByteString::ReplaceAllBytes(const FW_Char* string, FW_ByteCount numberBytes)
  165. {
  166.     ReplaceBytes(string, numberBytes, 0);
  167.     TruncateBytes(numberBytes);
  168. }
  169.  
  170. //----------------------------------------------------------------------------------------
  171. //    FW_CByteString::RetrieveBytes
  172. //----------------------------------------------------------------------------------------
  173.  
  174. void FW_CByteString::RetrieveBytes(FW_Char* destination,
  175.                                    FW_ByteCount numberBytes, 
  176.                                    FW_ByteCount position) const
  177. {
  178.     FW_ASSERT(destination != NULL);
  179.     FW_ASSERT(numberBytes >= 0);
  180.     FW_ASSERT(position>=0);
  181.     FW_ASSERT(position+numberBytes <= fByteLength+1);    // allow retrieval of NUL terminator
  182.     const FW_Byte* rep = fRepresentation;
  183.     const FW_Byte* start = rep + position;
  184.     if (numberBytes > 0)
  185.         FW_BlockMove(start, (FW_Byte*)destination, numberBytes);
  186. }
  187.  
  188. //----------------------------------------------------------------------------------------
  189. //    FW_CByteString::TruncateBytes
  190. //----------------------------------------------------------------------------------------
  191.  
  192. void FW_CByteString::TruncateBytes(FW_ByteCount bytePosition)
  193. {
  194.     if (bytePosition < fByteLength)
  195.         DeleteBytes(fByteLength - bytePosition, bytePosition);
  196. }
  197.  
  198. //----------------------------------------------------------------------------------------
  199. //    FW_CByteString::PrivSetByteLength
  200. //----------------------------------------------------------------------------------------
  201.  
  202. void FW_CByteString::PrivSetByteLength(FW_ByteCount bytes)
  203. {
  204.     fByteLength = bytes;
  205.     PrivNullTerminate();
  206. }
  207.  
  208.  
  209. //========================================================================================
  210. //    CLASS FW_CString
  211. //========================================================================================
  212.  
  213. //----------------------------------------------------------------------------------------
  214. //    FW_CString::~FW_CString
  215. //----------------------------------------------------------------------------------------
  216.  
  217. FW_CString::~FW_CString()
  218. {
  219. }
  220.  
  221. //----------------------------------------------------------------------------------------
  222. //    FW_CString::FW_CString (Default constructor)
  223. //----------------------------------------------------------------------------------------
  224.  
  225. FW_CString::FW_CString() :
  226.     FW_CByteString(),
  227.     fLength(0),
  228.     fCharWidth(sizeof(FW_Char))
  229. {
  230. }
  231.  
  232. //----------------------------------------------------------------------------------------
  233. //    FW_CString::FW_CString (Copy constructor)
  234. //----------------------------------------------------------------------------------------
  235.  
  236. FW_CString::FW_CString(const FW_CString &string) :
  237.     FW_CByteString(),
  238.     fLength(0),            // Derived class is responsible for updating cached lengths
  239.     fCharWidth(sizeof(FW_Char))
  240. {
  241.     FW_UNUSED(string);
  242. }
  243.  
  244. //----------------------------------------------------------------------------------------
  245. //    FW_CString::FW_CString (another constructor)
  246. //----------------------------------------------------------------------------------------
  247.  
  248. FW_CString::FW_CString(FW_ByteCount charWidth) :
  249.     FW_CByteString(),
  250.     fLength(0),
  251.     fCharWidth(charWidth)
  252. {
  253. }
  254.  
  255. //----------------------------------------------------------------------------------------
  256. //    FW_CString::operator=
  257. //----------------------------------------------------------------------------------------
  258.  
  259. FW_CString& FW_CString::operator=(const FW_CString& string)
  260. {
  261.     if (&string != this)
  262.     {
  263.         fCharWidth = string.GetCharWidth();
  264.         ReplaceAll(string);
  265.     }
  266.     return *this;
  267. }
  268.  
  269. //----------------------------------------------------------------------------------------
  270. //    FW_CString::operator=
  271. //----------------------------------------------------------------------------------------
  272.  
  273. FW_CString& FW_CString::operator=(const FW_Char* string)
  274. {
  275.     ReplaceAllBytes(string, FW_StringLength(string));
  276.     return *this;
  277. }
  278.  
  279. //----------------------------------------------------------------------------------------
  280. //    FW_CString::operator[]
  281. //----------------------------------------------------------------------------------------
  282.  
  283. FW_Char FW_CString::operator[](FW_CharacterPosition position) const
  284. {
  285.     FW_Char ch;
  286.     Retrieve(&ch, 1, position);
  287.     return ch;
  288. }
  289.  
  290. //----------------------------------------------------------------------------------------
  291. //    FW_CString::CharsToBytes
  292. //----------------------------------------------------------------------------------------
  293.  
  294. FW_ByteCount FW_CString::CharsToBytes(FW_CharacterCount numberChars,
  295.                                       FW_CharacterPosition position,
  296.                                       FW_ByteCount& bytePosition) const
  297. {
  298.     bytePosition = position * fCharWidth;
  299.     return numberChars * fCharWidth;
  300. }
  301.  
  302. //----------------------------------------------------------------------------------------
  303. //    FW_CString::Delete
  304. //----------------------------------------------------------------------------------------
  305.  
  306. void FW_CString::Delete(FW_CharacterCount numberChars, FW_CharacterPosition position)
  307. {
  308.     FW_ASSERT(numberChars >= 0);
  309.     FW_ASSERT(position>=0 && position<=fLength);
  310.     FW_ASSERT(position+numberChars <= fLength);
  311.     if (numberChars > 0)
  312.     {
  313.         FW_ByteCount bytePosition;
  314.         FW_ByteCount bytesToDelete = CharsToBytes(numberChars, position, bytePosition);
  315.         DeleteBytes(bytesToDelete, bytePosition);
  316.         PrivSetLength(fLength-numberChars);
  317.     }
  318. }
  319.         
  320. //----------------------------------------------------------------------------------------
  321. //    FW_CString::Insert
  322. //----------------------------------------------------------------------------------------
  323.  
  324. void FW_CString::Insert(const FW_Char* chars, 
  325.                         FW_CharacterCount numberChars,  
  326.                         FW_CharacterPosition position)
  327. {
  328.     FW_ASSERT(numberChars >= 0);
  329.     FW_ASSERT(position>=0 && position<=fLength);
  330.     if (numberChars > 0)
  331.     {
  332.         FW_ByteCount bytePosition;
  333.         FW_ByteCount numberBytes = CharsToBytes(numberChars, position, bytePosition);
  334.         InsertBytes(chars, numberBytes, bytePosition);
  335.         PrivSetLength(fLength + numberChars);
  336.     }
  337. }
  338.  
  339. //----------------------------------------------------------------------------------------
  340. //    FW_CString::ReplaceAllBytes
  341. //----------------------------------------------------------------------------------------
  342.  
  343. void FW_CString::ReplaceAllBytes(const FW_Char* string, FW_ByteCount numberBytes)    // Override
  344. {
  345.     FW_CByteString::ReplaceAllBytes(string, numberBytes);
  346.     PrivSetLength(fByteLength/fCharWidth);
  347. }
  348.  
  349. //----------------------------------------------------------------------------------------
  350. //    FW_CString::Replace
  351. //----------------------------------------------------------------------------------------
  352.  
  353. void FW_CString::Replace(const FW_Char* source,
  354.                          FW_CharacterCount numberChars, 
  355.                          FW_CharacterPosition position)
  356. {
  357.     FW_ASSERT(numberChars >= 0);
  358.     FW_ASSERT(position>=0 && position<=fLength);
  359.     if (numberChars > 0)
  360.     {
  361.         FW_CharacterCount charsToReplace = FW_Minimum(numberChars, fLength-position);
  362.         FW_ByteCount bytePosition;
  363.         FW_ByteCount numberBytes = CharsToBytes(numberChars, position, bytePosition);
  364.  
  365.         ReplaceBytes(source, numberBytes, bytePosition);
  366.         PrivSetLength(fLength - charsToReplace + numberChars);
  367.     }
  368. }
  369.  
  370. //----------------------------------------------------------------------------------------
  371. //    FW_CString::ReplaceAll
  372. //----------------------------------------------------------------------------------------
  373.  
  374. void FW_CString::ReplaceAll(const FW_CString& string)
  375. {
  376.     FW_ASSERT(string.GetCharWidth() == fCharWidth);    // ???
  377.     Replace((const FW_Char*)string, string.GetLength(), 0);
  378.     Truncate(string.GetLength());
  379. }
  380.  
  381. //----------------------------------------------------------------------------------------
  382. //    FW_CString::ReplaceAll
  383. //----------------------------------------------------------------------------------------
  384.  
  385. void FW_CString::ReplaceAll(const FW_Char* items, FW_CharacterCount numberItems)
  386. {
  387.     ReplaceAllBytes(items, numberItems);
  388. }
  389.  
  390. //----------------------------------------------------------------------------------------
  391. //    FW_CString::ReplaceAll
  392. //----------------------------------------------------------------------------------------
  393.  
  394. void FW_CString::ReplaceAll(const FW_Char* string)
  395. {
  396.     ReplaceAllBytes(string, FW_StringLength(string));
  397. }
  398.  
  399. //----------------------------------------------------------------------------------------
  400. //    FW_CString::Retrieve
  401. //----------------------------------------------------------------------------------------
  402.  
  403. void FW_CString::Retrieve(FW_Char* destination, FW_CharacterCount numberChars, FW_CharacterPosition position) const
  404. {
  405.     FW_ASSERT(numberChars >= 0);
  406.     FW_ASSERT(position>=0);
  407.     FW_ASSERT(position+numberChars <= fLength+1);    // allow retrieval of NUL terminator
  408.     FW_ByteCount bytePosition;
  409.     FW_ByteCount numberBytes = CharsToBytes(numberChars, position, bytePosition);
  410.     RetrieveBytes(destination, numberBytes, bytePosition);
  411. }
  412.  
  413. //----------------------------------------------------------------------------------------
  414. //    FW_CString::PrivSetLength
  415. //----------------------------------------------------------------------------------------
  416.  
  417. void FW_CString::PrivSetLength(FW_CharacterCount characters,
  418.                                FW_ByteCount bytes,
  419.                                FW_ByteCount charWidth)
  420. {
  421.     fLength = characters;
  422.     fCharWidth = charWidth;
  423.     PrivSetByteLength(bytes);
  424. }
  425.  
  426. //----------------------------------------------------------------------------------------
  427. //    FW_CString::Truncate
  428. //----------------------------------------------------------------------------------------
  429.  
  430. void FW_CString::Truncate(FW_CharacterPosition position)
  431. {
  432.     FW_ByteCount bytePosition;
  433.     CharsToBytes(0, position, bytePosition);
  434.     TruncateBytes(bytePosition);
  435.     PrivSetLength(position);
  436. }
  437.  
  438.  
  439. //----------------------------------------------------------------------------------------
  440. //    FW_CString::ToUpper
  441. //----------------------------------------------------------------------------------------
  442.  
  443. void FW_CString::ToUpper()
  444. {
  445.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  446.     tool->ToUpper(*this);
  447. }
  448.  
  449. //----------------------------------------------------------------------------------------
  450. //    FW_CString::ToLower
  451. //----------------------------------------------------------------------------------------
  452.  
  453. void FW_CString::ToLower()
  454. {
  455.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  456.     tool->ToLower(*this);
  457. }
  458.  
  459. //----------------------------------------------------------------------------------------
  460. //    FW_CString::Substitute
  461. //----------------------------------------------------------------------------------------
  462.  
  463. FW_Boolean FW_CString::Substitute(const FW_CString &searchString,
  464.                                   const FW_CString &substitutionString)
  465. {
  466.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  467.     return tool->Substitute(*this, searchString, substitutionString);
  468. }
  469.  
  470. //----------------------------------------------------------------------------------------
  471. //    FW_CString::FindSubString
  472. //----------------------------------------------------------------------------------------
  473.  
  474. FW_Boolean FW_CString::FindSubString(const FW_CString &subString,
  475.                                       FW_CharacterPosition &foundPosition,
  476.                                      FW_CharacterPosition startPosition) const
  477. {
  478.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  479.     return tool->FindSubString(*this, subString, foundPosition, startPosition);
  480. }
  481.  
  482. //----------------------------------------------------------------------------------------
  483. //    FW_CString::FindCharacter
  484. //----------------------------------------------------------------------------------------
  485.  
  486. FW_Boolean FW_CString::FindCharacter(FW_Char character,
  487.                                      FW_CharacterPosition &foundPosition,
  488.                                      FW_CharacterPosition startPosition) const
  489. {
  490.     FW_LChar longChar = character;
  491.     return this->FindCharacter(longChar, foundPosition, startPosition);
  492. }
  493.  
  494. FW_Boolean FW_CString::FindCharacter(FW_LChar character,
  495.                                      FW_CharacterPosition &foundPosition,
  496.                                      FW_CharacterPosition startPosition) const
  497. {
  498.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  499.     return tool->FindCharacter(*this, character, foundPosition, startPosition);
  500. }
  501.  
  502. //----------------------------------------------------------------------------------------
  503. //    FW_CString::FindWhiteSpace
  504. //----------------------------------------------------------------------------------------
  505.  
  506. FW_Boolean FW_CString::FindWhiteSpace(FW_CharacterPosition &foundPosition,
  507.                                       FW_CharacterPosition startPosition) const
  508. {
  509.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  510.     return tool->FindWhiteSpace(*this, foundPosition, startPosition);
  511. }
  512.  
  513. //----------------------------------------------------------------------------------------
  514. //    FW_CString::FindNonWhiteSpace
  515. //----------------------------------------------------------------------------------------
  516.  
  517. FW_Boolean FW_CString::FindNonWhiteSpace(FW_CharacterPosition &foundPosition,
  518.                                          FW_CharacterPosition startPosition) const
  519. {
  520.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  521.     return tool->FindNonWhiteSpace(*this, foundPosition, startPosition);
  522. }
  523.  
  524. //----------------------------------------------------------------------------------------
  525. //    FW_CString::Compare
  526. //----------------------------------------------------------------------------------------
  527.  
  528. int FW_CString::Compare(const FW_CString &string) const
  529. {
  530.     FW_CStringTool *tool = FW_CStringTool::GetCurrentStringTool();
  531.     return tool->CompareStrings(*this, string);
  532. }
  533.  
  534. //----------------------------------------------------------------------------------------
  535. //    FW_CString::operator==
  536. //----------------------------------------------------------------------------------------
  537.  
  538. FW_Boolean FW_CString::operator==(const FW_CString &string) const
  539. {
  540.     return (GetByteLength()==string.GetByteLength()) && (Compare(string) == kStringsEqual);
  541. }
  542.  
  543. FW_Boolean FW_CString::operator==(const char *string) const
  544. {
  545.     FW_CharacterCount stringLength = FW_StringLength(string);
  546.  
  547.     if (GetByteLength() != stringLength)
  548.         return FALSE;
  549.  
  550.     FW_CDynamicString aString(string, stringLength);
  551.  
  552.     return Compare(aString) == kStringsEqual;
  553. }
  554.  
  555. //----------------------------------------------------------------------------------------
  556. //    FW_CString::operator!=
  557. //----------------------------------------------------------------------------------------
  558.  
  559. FW_Boolean FW_CString::operator!=(const FW_CString &string) const
  560. {
  561.     return (GetByteLength()!=string.GetByteLength()) || (Compare(string) != kStringsEqual);
  562. }
  563.  
  564. FW_Boolean FW_CString::operator!=(const char *string) const
  565. {
  566.     FW_CharacterCount stringLength = FW_StringLength(string);
  567.  
  568.     if (GetByteLength() == stringLength)
  569.         return FALSE;
  570.  
  571.     FW_CDynamicString aString(string, stringLength);
  572.  
  573.     return Compare(aString) != kStringsEqual;
  574. }
  575.  
  576. //----------------------------------------------------------------------------------------
  577. //    FW_CString::operator<
  578. //----------------------------------------------------------------------------------------
  579.  
  580. FW_Boolean FW_CString::operator<(const FW_CString &string) const
  581. {
  582.     return Compare(string) == kStringOneLess;
  583. }
  584.  
  585. FW_Boolean FW_CString::operator<(const char *string) const
  586. {
  587.     FW_CharacterCount stringLength = FW_StringLength(string);
  588.     FW_CDynamicString aString(string, stringLength);
  589.  
  590.     return Compare(aString) == kStringOneLess;
  591. }
  592.  
  593. //----------------------------------------------------------------------------------------
  594. //    FW_CString::operator>
  595. //----------------------------------------------------------------------------------------
  596.  
  597. FW_Boolean FW_CString::operator>(const FW_CString &string) const
  598. {
  599.     return Compare(string) == kStringOneGreater;
  600. }
  601.  
  602. FW_Boolean FW_CString::operator>(const char *string) const
  603. {
  604.     FW_CharacterCount stringLength = FW_StringLength(string);
  605.     FW_CDynamicString aString(string, stringLength);
  606.  
  607.     return Compare(aString) == kStringOneGreater;
  608. }
  609.  
  610. //----------------------------------------------------------------------------------------
  611. //    FW_CString::operator<=
  612. //----------------------------------------------------------------------------------------
  613.  
  614. FW_Boolean FW_CString::operator<=(const FW_CString &string) const
  615. {
  616.     return Compare(string) != kStringOneGreater;
  617. }
  618.  
  619. FW_Boolean FW_CString::operator<=(const char *string) const
  620. {
  621.     FW_CharacterCount stringLength = FW_StringLength(string);
  622.     FW_CDynamicString aString(string, stringLength);
  623.  
  624.     return Compare(aString) != kStringOneGreater;
  625. }
  626.  
  627. //----------------------------------------------------------------------------------------
  628. //    FW_CString::operator>=
  629. //----------------------------------------------------------------------------------------
  630.  
  631. FW_Boolean FW_CString::operator>=(const FW_CString &string) const
  632. {
  633.     return Compare(string) != kStringOneLess;
  634. }
  635.  
  636. FW_Boolean FW_CString::operator>=(const char *string) const
  637. {
  638.     FW_CharacterCount stringLength = FW_StringLength(string);
  639.     FW_CDynamicString aString(string, stringLength);
  640.  
  641.     return Compare(aString) != kStringOneLess;
  642. }
  643.  
  644. //========================================================================================
  645. //    CLASS FW_CDynamicString
  646. //========================================================================================
  647.  
  648. //----------------------------------------------------------------------------------------
  649. //    FW_CDynamicString::~FW_CDynamicString
  650. //----------------------------------------------------------------------------------------
  651.  
  652. FW_CDynamicString::~FW_CDynamicString()
  653. {
  654.     FW_START_DESTRUCTOR
  655.     delete [] fRepresentation;
  656. }
  657.  
  658. //----------------------------------------------------------------------------------------
  659. //    FW_CDynamicString::FW_CDynamicString
  660. //----------------------------------------------------------------------------------------
  661.  
  662. FW_CDynamicString::FW_CDynamicString(const FW_CDynamicString &string) :
  663.     FW_CString()
  664. {
  665.     fCharWidth = string.GetCharWidth();
  666.     FW_ByteCount numberBytes = string.GetByteLength();
  667.     AllocateRepresentation(numberBytes);
  668.     Append(string);
  669.     FW_END_CONSTRUCTOR
  670. }
  671.  
  672. //----------------------------------------------------------------------------------------
  673. //    FW_CDynamicString::FW_CDynamicString
  674. //----------------------------------------------------------------------------------------
  675.  
  676. FW_CDynamicString::FW_CDynamicString(const FW_CString &string) :
  677.     FW_CString()
  678. {
  679.     fCharWidth = string.GetCharWidth();
  680.     FW_ByteCount numberBytes = string.GetByteLength();
  681.     AllocateRepresentation(numberBytes);
  682.     Append(string);
  683.     FW_END_CONSTRUCTOR
  684. }
  685.  
  686. //----------------------------------------------------------------------------------------
  687. //    FW_CDynamicString::FW_CDynamicString
  688. //----------------------------------------------------------------------------------------
  689.  
  690. FW_CDynamicString::FW_CDynamicString(const FW_Char *items, FW_CharacterCount numberItems) :
  691.     FW_CString()
  692. {
  693.     FW_ByteCount numberBytes = FW_CharsToBytes(numberItems);
  694.     AllocateRepresentation(numberBytes);
  695.     Append(items, numberItems);
  696.     FW_END_CONSTRUCTOR
  697. }
  698.  
  699. //----------------------------------------------------------------------------------------
  700. //    FW_CDynamicString::FW_CDynamicString
  701. //----------------------------------------------------------------------------------------
  702.  
  703. FW_CDynamicString::FW_CDynamicString(const FW_Char *items)
  704. {
  705.     FW_CharacterCount numberItems = FW_StringLength(items);
  706.     FW_ByteCount numberBytes = FW_CharsToBytes(numberItems);
  707.     AllocateRepresentation(numberBytes);
  708.     Append(items, numberItems);
  709.     FW_END_CONSTRUCTOR
  710. }
  711.  
  712. //----------------------------------------------------------------------------------------
  713. //    FW_CDynamicString::FW_CDynamicString
  714. //----------------------------------------------------------------------------------------
  715.  
  716. FW_CDynamicString::FW_CDynamicString(FW_ByteCount capacity) :
  717.     FW_CString()
  718. {
  719.     AllocateRepresentation(capacity);
  720.     FW_END_CONSTRUCTOR
  721. }
  722.  
  723. //----------------------------------------------------------------------------------------
  724. //    FW_CDynamicString::FW_CDynamicString
  725. //----------------------------------------------------------------------------------------
  726.  
  727. FW_CDynamicString::FW_CDynamicString(FW_ByteCount capacity, FW_ByteCount charWidth) :
  728.     FW_CString(charWidth)
  729. {
  730.     AllocateRepresentation(capacity);
  731.     FW_END_CONSTRUCTOR
  732. }
  733.  
  734. //----------------------------------------------------------------------------------------
  735. //    FW_CDynamicString::operator=
  736. //----------------------------------------------------------------------------------------
  737.  
  738. FW_CString& FW_CDynamicString::operator=(const FW_CDynamicString& string)
  739. {
  740.     if (&string != this)
  741.     {
  742.         fCharWidth = string.GetCharWidth();
  743.         ReplaceAll(string);
  744.     }
  745.     return *this;
  746. }
  747.  
  748. //----------------------------------------------------------------------------------------
  749. //    FW_CDynamicString::operator=
  750. //----------------------------------------------------------------------------------------
  751.  
  752. FW_CString& FW_CDynamicString::operator=(const FW_CString& string)
  753. {
  754.     fCharWidth = string.GetCharWidth();
  755.     ReplaceAll(string);
  756.     return *this;
  757. }
  758.  
  759. //----------------------------------------------------------------------------------------
  760. //    FW_CDynamicString::operator=
  761. //----------------------------------------------------------------------------------------
  762.  
  763. FW_CString& FW_CDynamicString::operator=(const FW_Char* string)
  764. {
  765.     ReplaceAllBytes(string, FW_StringLength(string));
  766.     return *this;
  767. }
  768.  
  769. //----------------------------------------------------------------------------------------
  770. //    FW_CDynamicString::GrowCapacity
  771. //----------------------------------------------------------------------------------------
  772.  
  773. FW_ByteCount FW_CDynamicString::GrowCapacity(FW_ByteCount capacityNeeded)
  774. {
  775.     PrivResize(capacityNeeded);
  776.     return fCapacity;
  777. }
  778.  
  779. //----------------------------------------------------------------------------------------
  780. //    FW_CDynamicString::PrivResize
  781. //----------------------------------------------------------------------------------------
  782.  
  783. void FW_CDynamicString::PrivResize(FW_ByteCount newCapacity)
  784. {
  785.     if (fCapacity < newCapacity)
  786.     {
  787.         FW_Byte *newRep = new FW_Byte[newCapacity+sizeof(FW_Char)];
  788.         FW_BlockMove(fRepresentation, newRep, fCapacity+sizeof(FW_Char));
  789.         delete [] fRepresentation;
  790.         fRepresentation = newRep;
  791.         fCapacity = newCapacity;
  792.     }
  793. }
  794.  
  795. //========================================================================================
  796. //    CLASS FW_CStringReader
  797. //========================================================================================
  798.  
  799. //----------------------------------------------------------------------------------------
  800. //    FW_CStringReader::FW_CStringReader
  801. //----------------------------------------------------------------------------------------
  802.  
  803. FW_CStringReader::FW_CStringReader(const FW_CString& string) :
  804.     FW_CTextReader(string.fRepresentation,
  805.                     string.fRepresentation+string.GetByteLength(),
  806.                     string.GetByteLength())
  807. {
  808.     fBytesPerChar = string.GetCharWidth();
  809. }
  810.  
  811. //----------------------------------------------------------------------------------------
  812. //    FW_CStringReader::FW_CStringReader
  813. //----------------------------------------------------------------------------------------
  814.  
  815. FW_CStringReader::FW_CStringReader(    const FW_CString &string,
  816.                                     FW_BytePosition start,
  817.                                     FW_ByteCount length) :
  818.     FW_CTextReader(string.fRepresentation+start,
  819.                    string.fRepresentation+start+length,
  820.                    length)
  821. {
  822.     fBytesPerChar = string.GetCharWidth();
  823. }
  824.  
  825. //----------------------------------------------------------------------------------------
  826. //    FW_CStringReader::FW_CStringReader
  827. //----------------------------------------------------------------------------------------
  828.  
  829. FW_CStringReader::~FW_CStringReader()
  830. {
  831. }
  832.  
  833. //----------------------------------------------------------------------------------------
  834. //    FW_CStringReader::DoGetNextBuffer
  835. //----------------------------------------------------------------------------------------
  836.  
  837. void FW_CStringReader::DoGetNextBuffer()
  838. {
  839.     FW_ASSERT(FALSE);    // one contiguous block, there is no next buffer
  840. }
  841.  
  842. //----------------------------------------------------------------------------------------
  843. //    FW_CStringReader::DoGetPreviousBuffer
  844. //----------------------------------------------------------------------------------------
  845.  
  846. void FW_CStringReader::DoGetPreviousBuffer()
  847. {
  848.     FW_ASSERT(FALSE);    // one contiguous block, there is no previous buffer
  849. }
  850.  
  851. //========================================================================================
  852. //    CLASS FW_CStringWriter
  853. //========================================================================================
  854.  
  855. //----------------------------------------------------------------------------------------
  856. //    FW_CStringWriter::FW_CStringWriter
  857. //----------------------------------------------------------------------------------------
  858.  
  859. FW_CStringWriter::FW_CStringWriter(    FW_CString &string, 
  860.                                     FW_TextWriterMode mode,
  861.                                     unsigned short bufferSize) : 
  862.     FW_CTextWriter(0, 0), 
  863.     fString(string),
  864.     fBufferSize(bufferSize),
  865.     fMode(mode)
  866. {
  867.     fBuffer = new FW_Byte[fBufferSize];
  868.     fStart = fBuffer;
  869.     fNext = fBuffer;
  870.     fLimit = fBuffer + fBufferSize;
  871.     if (mode == FW_kTextAppend)
  872.         fBufferSum = string.GetByteLength();
  873.     FW_END_CONSTRUCTOR
  874. }
  875.  
  876. //----------------------------------------------------------------------------------------
  877. //    FW_CStringWriter::~FW_CStringWriter
  878. //----------------------------------------------------------------------------------------
  879.  
  880. FW_CStringWriter::~FW_CStringWriter()
  881. {
  882.     FW_START_DESTRUCTOR
  883.     FlushAndUpdateText();
  884.     delete [] fBuffer;
  885. }
  886.  
  887. //----------------------------------------------------------------------------------------
  888. //    FW_CStringWriter::DoFlushBuffer
  889. //----------------------------------------------------------------------------------------
  890.  
  891. void FW_CStringWriter::DoFlushBuffer(FW_ByteCount bytesToFlush)    // Override
  892. {
  893.     FW_CString& string = fString;    // MetroWerks bug workaround [AMB]
  894.     
  895.     if (bytesToFlush > 0)
  896.     {
  897.         if (fMode == FW_kTextWriteOver)
  898.             string.Replace((FW_Char*) fBuffer, bytesToFlush, fBufferSum);
  899.         else    // (fMode == FW_kTextAppend)
  900.             string.Append((FW_Char*) fBuffer, bytesToFlush);
  901.         fNext = fBuffer;    // reset next pointer so buffer looks empty
  902.     }
  903. }
  904.  
  905. //----------------------------------------------------------------------------------------
  906. //    FW_CStringWriter::DoGetNextBuffer
  907. //----------------------------------------------------------------------------------------
  908.  
  909. void FW_CStringWriter::DoGetNextBuffer()    // Override
  910. {
  911.     fNext = fBuffer;    // we only use one buffer, so just reset fNext to the start
  912. }
  913.